home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / INTLDEMO.PAK / FILELIST.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  11KB  |  471 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1996 by Borland International
  3. //   filelist.cpp
  4. //----------------------------------------------------------------------------
  5. #include <owl\pch.h>
  6. #include <owl\dialog.h>
  7. #include <owl\dc.h>
  8. #include <owl\listbox.h>
  9. #include <locale.h>
  10. #include <io.h>
  11. #include <time.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <dir.h>
  16. #include <ctype.h>
  17. #include <math.h>
  18. #include <cstring.h>
  19. #include <bwcc.h>
  20.  
  21. #include "intldemo.h"
  22. #include "filelist.h"
  23.  
  24. char* formatVal(char*, long);
  25.  
  26. //
  27. //  class TFileViewer
  28. //  ----- -----------
  29. //
  30. //  TFileView displays up to 100 chars of each of the first 100 lines
  31. //  of a file in a listbox. Allows sorting by lines.
  32. //
  33. class TFileViewer : public TDialog {
  34.   public:
  35.     TFileViewer(TWindow* parent, TModule* module, char* fileName, TResId resourceId = ID_FILEVIEWER);
  36.     ~TFileViewer();
  37.  
  38.   protected:
  39.     void CmSort(uint);
  40.     void SetupWindow();
  41.     enum {maxLines = 100, maxLineLength = 100};
  42.     TListBox* ListBox;
  43.     TIArrayAsVector<string> Unsorted;
  44.     TISArrayAsVector<string> Sorted;
  45.     char* Caption;
  46.  
  47.   DECLARE_RESPONSE_TABLE(TFileViewer);
  48. };
  49.  
  50. DEFINE_RESPONSE_TABLE1(TFileViewer, TDialog)
  51.   EV_CHILD_NOTIFY_ALL_CODES(ID_SORTBUT, CmSort),
  52. END_RESPONSE_TABLE;
  53.  
  54. TFileViewer::TFileViewer(TWindow* parent, TModule* module, char* fileName, TResId resourceId)
  55.   : TDialog(parent, resourceId, module),
  56.      Unsorted(maxLines), Sorted(maxLines)
  57. {
  58.   Sorted.OwnsElements(0); // strings belong to both Sorted and Unsorted arrays
  59.                                       // only one container should delete the strings
  60.   Caption = 0;
  61.  
  62.   int lines = 0;
  63.   ifstream inputFile(fileName);
  64.   if (!inputFile.fail()) {
  65.     Caption = new char [strlen(fileName)+1];
  66.     strcpy(Caption, fileName);
  67.     while(!inputFile.eof() && lines++ < maxLines) {
  68.     char buf[maxLineLength];
  69.     inputFile.get(buf, sizeof(buf) - 1);
  70.     string* s = new string(buf);
  71.     Unsorted.Add(s);
  72.     Sorted.Add(s);
  73.     // if we're not at the end of the line, try to jump to the next line
  74.     if (inputFile.get() != '\n')
  75.       inputFile.ignore(100, '\n');
  76.     }
  77.     inputFile.close();
  78.   }
  79.   ListBox = new TListBox(this, ID_FILELISTBOX, module);
  80. }
  81.  
  82. TFileViewer::~TFileViewer()
  83. {
  84.   if (Caption)
  85.     delete [] Caption;
  86. }
  87.  
  88. void TFileViewer::SetupWindow()
  89. {
  90.   TDialog::SetupWindow();
  91.   SetCaption(Caption);
  92.   for (int i = 0; i < Unsorted.GetItemsInContainer(); i++) {
  93.     ListBox->AddString(Unsorted[i]->c_str());
  94.   }
  95. }
  96.  
  97. void TFileViewer::CmSort(uint)
  98. {
  99.   ListBox->ClearList();
  100.   for (int i = 0; i < Sorted.GetItemsInContainer(); i++) {
  101.     ListBox->AddString(Sorted[i]->c_str());
  102.   }
  103.   ListBox->SetSelIndex(0);
  104. }
  105.  
  106. //
  107. // class TDateTime
  108. // ----- --------
  109. //
  110. // TDateTime is used to convert a file's date/time value into a struct tm.
  111. //
  112. class TDateTime {
  113.   private:
  114.     struct filetime
  115.     {
  116.     #if defined (__FLAT__)
  117.       unsigned short ftime;
  118.       unsigned short fdate;
  119.     #else
  120.       int ftime;
  121.       int fdate;
  122.     #endif
  123.     };
  124.  
  125.     union dosfiletime
  126.     {
  127.       filetime ft;
  128.       struct ftime ftime;
  129.     };
  130.  
  131.     dosfiletime DosFileTime;
  132.     struct date Date;
  133.     struct time Time;
  134.  
  135.   public:
  136.     TDateTime(int ftime, int fdate);
  137.     struct tm* tmvalue();
  138. };
  139.  
  140. #pragma warn -sig
  141. TDateTime::TDateTime(int ftime, int fdate)
  142. {
  143.   DosFileTime.ft.ftime = ftime;
  144.   DosFileTime.ft.fdate = fdate;
  145.  
  146.   Time.ti_sec  = DosFileTime.ftime.ft_tsec * 2;
  147.   Time.ti_min  = DosFileTime.ftime.ft_min;
  148.   Time.ti_hour = DosFileTime.ftime.ft_hour;
  149.   Time.ti_hund = 0;
  150.  
  151.   Date.da_day  = DosFileTime.ftime.ft_day;
  152.   Date.da_mon  = DosFileTime.ftime.ft_month;
  153.   Date.da_year = DosFileTime.ftime.ft_year + 1980;
  154. }
  155. #pragma warn +sig
  156.  
  157. struct tm* TDateTime::tmvalue()
  158. {
  159.   time_t t;
  160.   t = dostounix(&Date, &Time);
  161.   return localtime (&t);
  162. }
  163.  
  164. //
  165. // class TFileListBox
  166. // ----- ------------
  167. //
  168. // TFileListBox is used to display file information.
  169. // Note we are using our own sort functions rather than Windows'
  170. // default sorting. This allows different instances of the program to
  171. // demonstrate the different sorting/collating sequences of different locales.
  172. //
  173. class TFileListBox : public TListBox
  174. {
  175.   public:
  176.     TFileListBox(TWindow* parent, int ResourceId, TModule* Module);
  177.     void ToLower();
  178.     void FillListBox();
  179.     void GetDirList();
  180.     void EvLButtonDblClk(uint, TPoint&);
  181.     void Sort();
  182.     void ChangeDir();
  183.     void View();
  184.  
  185.   private:
  186.     // Structure containing file information to be displayed in the
  187.     // FileListBox.
  188.     //
  189.     struct FileRec
  190.     {
  191.       char name[13], datetime[100],  sizeStr[30];
  192.       long fsize;
  193.       unsigned long attrib;
  194.  
  195.       // functions used by sorted arrays
  196.       int operator<(const FileRec& r) const
  197.       {
  198.         return (strcoll(name, r.name) < 0) ? 1 : 0;
  199.       }
  200.  
  201.       int operator==(const FileRec& r) const
  202.       {
  203.         return (strcoll(name, r.name) == 0) ? 1 : 0;
  204.       }
  205.     };
  206.  
  207.     // Font to display the filelistbox - we want a non-proportional
  208.     // font for formatting reasons
  209.     class TFileListFont : public TFont
  210.     {
  211.       private:
  212.         int HeightInPixels(int pointSize)
  213.         {
  214.           TScreenDC  dc;
  215.           return MulDiv(-pointSize, dc.GetDeviceCaps(LOGPIXELSY), 72);
  216.         }
  217.  
  218.       public:
  219.         TFileListFont() : TFont ("Courier New", HeightInPixels(8)) {}
  220.     };
  221.  
  222.     int IsSorted;
  223.     int NFiles;
  224.     TIArrayAsVector<FileRec> FRArray;
  225.     TISArrayAsVector<FileRec> SFRArray;
  226.     enum cases {upper, lower};
  227.     cases CurrCase;
  228.     enum sorting {sorted, unsorted};
  229.     sorting CurrSort;
  230.     TModule* Module;
  231.     TFileListFont Font;
  232.  
  233.   protected:
  234.     void SetupWindow();
  235.  
  236.   DECLARE_RESPONSE_TABLE(TFileListBox);
  237. };
  238.  
  239. DEFINE_RESPONSE_TABLE1(TFileListBox, TListBox)
  240.    EV_WM_LBUTTONDBLCLK,
  241. END_RESPONSE_TABLE;
  242.  
  243. TFileListBox::TFileListBox(TWindow* parent, int resourceId, TModule* module) :
  244.       TListBox(parent, resourceId, module),
  245.       FRArray(100, 0, 10), SFRArray(100, 0, 10), CurrCase(upper), CurrSort(unsorted)
  246. {
  247.   Module = module;
  248.   SFRArray.OwnsElements(0);
  249. }
  250.  
  251. void TFileListBox::SetupWindow()
  252. {
  253.   TListBox::SetupWindow();
  254.   SetWindowFont(Font, 0);
  255.   GetDirList();
  256.   FillListBox();
  257.   SetSelIndex(0);
  258. }
  259.  
  260. void TFileListBox::Sort()
  261. {
  262.   CurrSort = (CurrSort == sorted) ? unsorted : sorted;
  263.   char buf[MAXFILE + MAXEXT + 1];
  264.   GetSelString(buf, sizeof(buf));
  265.   FillListBox();
  266.   SetSelString(buf, 0);
  267. }
  268.  
  269. void TFileListBox::View()
  270. {
  271.   if (GetSelIndex() >= 0) {
  272.     char buf[100];
  273.     GetSelString(buf, sizeof(buf));
  274.  
  275.     if (strstr(buf, "<DIR>"))
  276.       ChangeDir();
  277.     else {
  278.       char* s = strchr(buf, ' ');
  279.       if (s)
  280.         *s = 0;
  281.       TFileViewer(Parent, Module, buf).Execute();
  282.     }
  283.   }
  284. }
  285.  
  286.  
  287. void TFileListBox::EvLButtonDblClk(uint, TPoint&)
  288. {
  289.   View();   // view the file or directory
  290. }
  291.  
  292. void TFileListBox::GetDirList()
  293. {
  294.   SFRArray.Flush();
  295.   FRArray.Flush();
  296.   struct ffblk ffblk;
  297.   struct tm* tm;
  298.   TDateTime* dt;
  299.   NFiles = 0;
  300.   int done = findfirst("*.*", &ffblk, 0x3f);
  301.   while (!done) {
  302.     FileRec* f = new FileRec;
  303. #if !defined (__FLAT__)
  304.     OemToAnsiBuff(ffblk.ff_name, ffblk.ff_name, strlen(ffblk.ff_name));
  305. #endif
  306.     if (CurrCase == lower) {
  307.       strlwr(ffblk.ff_name);
  308.     }
  309.     strncpy(f->name, ffblk.ff_name, 12);
  310.     f->name[12] = '\0';
  311.     dt = new TDateTime(ffblk.ff_ftime, ffblk.ff_fdate);
  312.     tm = dt->tmvalue();
  313.     delete dt;
  314.     f->attrib = ffblk.ff_attrib;
  315.     f->fsize = ffblk.ff_fsize;
  316.     formatVal(f->sizeStr, ffblk.ff_fsize);
  317.     strftime(f->datetime, 100, "%c", tm);
  318.     FRArray.Add(f);
  319.     SFRArray.Add(f);
  320.     done = findnext(&ffblk);
  321.   }
  322. }
  323.  
  324. void TFileListBox::ChangeDir()
  325. {
  326.   char buf[MAXFILE + MAXEXT + 1];
  327.   if (GetSelString(buf, sizeof(buf)))
  328.   {
  329.     for (int i = 0; i < sizeof buf; i++)
  330.       if (buf[i] == ' ') {
  331.       buf[i] = 0;
  332.       break;
  333.       }
  334.     if (!chdir(buf)) {
  335.       GetDirList();
  336.       FillListBox();
  337.     }
  338.   }
  339. }
  340.  
  341. void TFileListBox::ToLower()
  342. {
  343.   int selection = GetSelIndex();
  344.   if (CurrCase == upper) {
  345.     for (int i = 0; i < FRArray.GetItemsInContainer(); i++)
  346.       strlwr(FRArray[i]->name);
  347.     CurrCase = lower;
  348.     FillListBox();
  349.   }
  350.   else {
  351.     for (int i = 0; i < FRArray.GetItemsInContainer(); i++)
  352.       strupr(FRArray[i]->name);
  353.     CurrCase = upper;
  354.     FillListBox();
  355.   }
  356.   SetSelIndex(selection);
  357. }
  358.  
  359. void TFileListBox::FillListBox()
  360. {
  361.   char lbformat[] = "%-14.14s\t%-7s\t%10s";
  362.   char s[120];
  363.   SetRedraw(FALSE);
  364.   // Japanese Windows 3.0 repaints horribly with SETREDRAW switched on!
  365.   ClearList();
  366.   int i;
  367.   switch(CurrSort)
  368.   {
  369.     case sorted:
  370.       for (i = 0; i < SFRArray.GetItemsInContainer(); i++) {
  371.         sprintf(s, lbformat, SFRArray[i]->name, SFRArray[i]->datetime,
  372.           ((SFRArray[i]->attrib & FA_DIREC) ? ("<DIR>") : (SFRArray[i]->sizeStr)));
  373.         AddString(s);
  374.       }
  375.       break;
  376.  
  377.     case unsorted:
  378.       for (i = 0; i < FRArray.GetItemsInContainer(); i++) {
  379.         sprintf(s, lbformat, FRArray[i]->name, FRArray[i]->datetime,
  380.             ((FRArray[i]->attrib & FA_DIREC) ? ("<DIR>") : (FRArray[i]->sizeStr)));
  381.           AddString(s);
  382.       }
  383.       break;
  384.   }
  385.   SetRedraw(TRUE);
  386. }
  387.  
  388. TFileListDialog::TFileListDialog(TWindow* parent, TModule* Module, int ResourceId)
  389.       :TDialog(parent, ResourceId, Module)
  390. {
  391.   char buf[MAXPATH];
  392.  
  393.   ListBox =  new TFileListBox(this, ID_FILELISTBOX, Module);
  394.   ViewButton = new TButton(this, ID_VIEWBUTTON, Module);
  395.  
  396.   getcwd(buf, MAXPATH);
  397.   StartDir = new char [strlen(buf)+1];
  398.   strcpy(StartDir, buf);
  399. }
  400.  
  401. TFileListDialog::~TFileListDialog()
  402. {
  403.   chdir(StartDir);
  404.   delete [] StartDir;
  405. }
  406.  
  407. void TFileListDialog::Sort(uint)
  408. {
  409.   ListBox->Sort();
  410. }
  411.  
  412. void TFileListDialog::ToLower(uint)
  413. {
  414.   ListBox->ToLower();
  415. }
  416.  
  417. void TFileListDialog::View(uint)
  418. {
  419.   ListBox->View();
  420. }
  421.  
  422. void TFileListDialog::Help(uint)
  423. {
  424. }
  425.  
  426. DEFINE_RESPONSE_TABLE1(TFileListDialog, TDialog)
  427.   EV_CHILD_NOTIFY_ALL_CODES(ID_SORTBUT, Sort),
  428.   EV_CHILD_NOTIFY_ALL_CODES(ID_TOLOWERBUT, ToLower),
  429.   EV_CHILD_NOTIFY_ALL_CODES(ID_VIEWBUTTON, View),
  430.   EV_CHILD_NOTIFY_ALL_CODES(IDHELP, Help),
  431. END_RESPONSE_TABLE;
  432.  
  433. char* formatVal(char* s, long l)
  434. {
  435.   lconv* conv = localeconv();
  436.   sprintf(s, "%ld", l);
  437.  
  438.   int group = *conv->grouping;
  439.  
  440.   if (!group)
  441.     return s; // no grouping info, quit
  442.  
  443.   int sLen = strlen(s);
  444.  
  445.   if (sLen <= group) // not enough chars to worry about.
  446.     return s;
  447.  
  448.   int tempLen =  sLen + (sLen /3);
  449.   if (!(int)fmod(sLen, 3))
  450.     tempLen--;
  451.  
  452.   char tempStr[30];
  453.   tempStr[tempLen--] = s[sLen--];
  454.  
  455.   while (sLen >= group) {
  456.     int groupCount = 0;
  457.     while (groupCount < group) {
  458.       tempStr[tempLen--] = s[sLen--];
  459.       groupCount++;
  460.     }
  461.     tempStr[tempLen--] = *(conv->thousands_sep);
  462.   } 
  463.  
  464.   while (sLen >= 0)
  465.     tempStr[tempLen--] = s[sLen--];
  466.  
  467.   strcpy(s, tempStr);
  468.  
  469.   return s;
  470. }
  471.